#include "window_delegate.h"

#include <stdio.h>
#include <stddef.h>

#include "capi/views/cef_display_capi.h"
#include "capi/cef_app_capi.h"

void CEF_CALLBACK on_window_created(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    LOG_DEBUG("start");
    window_delegate *delegate = (window_delegate *)self;
    cef_view_t *view = (cef_view_t *)delegate->browser_view;
    window->base.add_child_view(&window->base, view);
    // window_delegate_ref->browser_view->base.request_focus(&window_delegate_ref->browser_view->base);
    // 设置图标
    // 设置标题
    if (delegate->is_devtools) { 
        set_title(window, "Cangjie CEF 开发工具");
    } else {
        set_title(window, delegate->title);
    }
    set_icon_png(window, delegate->icon_png_path);
    window->show(window);
    LOG_DEBUG("on_window_created");
}

void CEF_CALLBACK on_window_closing(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    window_delegate *delegate = (window_delegate *)self;
    // free(delegate);
    LOG_DEBUG("on_window_closing slef free");
}

void CEF_CALLBACK on_window_destroyed(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    window_delegate *delegate = (window_delegate *)self;
    delegate->browser_view = NULL;
    free(delegate->icon_png_path);
    free(delegate->title);
    free(delegate);
    LOG_DEBUG("on_window_destroyed resource free char* and self");
}


void CEF_CALLBACK on_window_activation_changed(struct _cef_window_delegate_t* self, struct _cef_window_t* window, int active) {}

void CEF_CALLBACK on_window_bounds_changed(struct _cef_window_delegate_t *self, struct _cef_window_t *window, const cef_rect_t *new_bounds) {}

void CEF_CALLBACK on_window_fullscreen_transition(struct _cef_window_delegate_t *self, struct _cef_window_t *window, int is_completed) {}

cef_rect_t CEF_CALLBACK get_initial_bounds(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    window_delegate *window_delegate_ptr = (window_delegate *)self;
    cef_display_t *display = cef_display_get_primary();
    cef_rect_t rect = display->get_bounds(display);
 
    rect.x = (rect.width - window_delegate_ptr->width) / 2;
    rect.y = (rect.height - window_delegate_ptr->height) / 2;

    rect.width = window_delegate_ptr->width;
    rect.height = window_delegate_ptr->height;
    return rect;
}

struct _cef_window_t* CEF_CALLBACK get_parent_window( struct _cef_window_delegate_t* self, struct _cef_window_t* window, int* is_menu, int* can_activate_menu) {
    return NULL;
}

int CEF_CALLBACK is_window_modal_dialog(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    return 0;
}

cef_show_state_t CEF_CALLBACK get_initial_show_state(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    return CEF_SHOW_STATE_NORMAL;
}

int CEF_CALLBACK is_frameless(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    window_delegate *delegate = (window_delegate *) self;
    if (delegate -> is_frameless && delegate->is_devtools == 0) {
        return 1;
    }
    return 0;
}

int CEF_CALLBACK with_standard_window_buttons(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    return !is_frameless(self, window);
}

int CEF_CALLBACK get_titlebar_height(struct _cef_window_delegate_t* self, struct _cef_window_t* window, float* titlebar_height) {
    return 0;
}

cef_state_t CEF_CALLBACK accepts_first_mouse(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    return STATE_DEFAULT;
}

int CEF_CALLBACK can_resize(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    return 1;
}

int CEF_CALLBACK can_maximize(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    return 1;
}

int CEF_CALLBACK can_minimize(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    return 1;
}

int CEF_CALLBACK can_close(struct _cef_window_delegate_t* self, struct _cef_window_t* window) {
    return 1;
}

int CEF_CALLBACK on_accelerator(struct _cef_window_delegate_t* self, struct _cef_window_t* window, int command_id) {
    return 0;
}

int CEF_CALLBACK on_key_event(struct _cef_window_delegate_t* self, struct _cef_window_t* window, const cef_key_event_t* event) {
    return 0;
}

void CEF_CALLBACK on_theme_colors_changed(struct _cef_window_delegate_t *self, struct _cef_window_t *window, int chrome_theme) {}

cef_runtime_style_t CEF_CALLBACK get_window_runtime_style(struct _cef_window_delegate_t* self) {
    return CEF_RUNTIME_STYLE_DEFAULT;
}

int CEF_CALLBACK get_linux_window_properties(struct _cef_window_delegate_t* self, struct _cef_window_t* window, struct _cef_linux_window_properties_t* properties) {
    return 0;
}

// cef_panel_delegate_t base;--------------------------------------
cef_size_t CEF_CALLBACK get_preferred_size( struct _cef_view_delegate_t *self, struct _cef_view_t *view) {
    cef_size_t size = {};
    return size;
}

cef_size_t CEF_CALLBACK get_minimum_size(struct _cef_view_delegate_t* self, struct _cef_view_t* view) {
    cef_size_t size = {};
    return size;
}

cef_size_t CEF_CALLBACK get_maximum_size(struct _cef_view_delegate_t *self, struct _cef_view_t *view) {
    cef_size_t size = {};
    return size;
}

int CEF_CALLBACK get_height_for_width(struct _cef_view_delegate_t *self, struct _cef_view_t *view, int width) {
    return 0;
}

void CEF_CALLBACK on_parent_view_changed(struct _cef_view_delegate_t *self, struct _cef_view_t *view, int added, struct _cef_view_t *parent) {}

void CEF_CALLBACK on_child_view_changed(struct _cef_view_delegate_t *self, struct _cef_view_t *view, int added, struct _cef_view_t *child) {}

void CEF_CALLBACK on_window_changed(struct _cef_view_delegate_t *self, struct _cef_view_t *view, int added) {}

void CEF_CALLBACK on_layout_changed(struct _cef_view_delegate_t* self, struct _cef_view_t* view, const cef_rect_t* new_bounds) {}

void CEF_CALLBACK on_focus(struct _cef_view_delegate_t *self, struct _cef_view_t *view) {}

void CEF_CALLBACK on_blur(struct _cef_view_delegate_t *self, struct _cef_view_t *view) {}

void CEF_CALLBACK on_theme_changed(struct _cef_view_delegate_t *self, struct _cef_view_t *view) {}

window_delegate *_create_window_delegate(cef_browser_view_t *browser_view, int width, int heigth, char *icon_png_path, char *title, int isFrameless, int is_devtools) {
    window_delegate *window_delegate_ptr = (window_delegate *)calloc(1, sizeof(window_delegate));

    window_delegate_ptr->browser_view = browser_view;
    window_delegate_ptr->width = width;
    window_delegate_ptr->height = heigth;
    if (icon_png_path != NULL) {
        window_delegate_ptr->icon_png_path = (char*)malloc(strlen(icon_png_path) + 1);
        strcpy(window_delegate_ptr->icon_png_path, icon_png_path);
    }
    if (title != NULL) {
        window_delegate_ptr->title = (char*)malloc(strlen(title) + 1);
        strcpy(window_delegate_ptr->title, title);
    }
    window_delegate_ptr->is_devtools = is_devtools;
    window_delegate_ptr->is_frameless = isFrameless;

    // init bptr
    window_delegate_ptr->cef_window_delegate.base.base.base.size = sizeof(cef_window_delegate_t);
    window_delegate_ptr->cef_window_delegate.base.base.get_preferred_size = get_preferred_size;
    window_delegate_ptr->cef_window_delegate.base.base.get_maximum_size = get_maximum_size;
    window_delegate_ptr->cef_window_delegate.base.base.get_minimum_size = get_minimum_size;
    window_delegate_ptr->cef_window_delegate.base.base.get_height_for_width = get_height_for_width;
    window_delegate_ptr->cef_window_delegate.base.base.on_parent_view_changed = on_parent_view_changed;
    window_delegate_ptr->cef_window_delegate.base.base.on_child_view_changed = on_child_view_changed;
    window_delegate_ptr->cef_window_delegate.base.base.on_window_changed = on_window_changed;
    window_delegate_ptr->cef_window_delegate.base.base.on_layout_changed = on_layout_changed;
    window_delegate_ptr->cef_window_delegate.base.base.on_focus = on_focus;
    window_delegate_ptr->cef_window_delegate.base.base.on_blur = on_blur;
    window_delegate_ptr->cef_window_delegate.base.base.on_theme_changed = on_theme_changed;
    window_delegate_ptr->cef_window_delegate.on_window_created = on_window_created;
    window_delegate_ptr->cef_window_delegate.on_window_closing = on_window_closing;
    window_delegate_ptr->cef_window_delegate.on_window_destroyed = on_window_destroyed;
    window_delegate_ptr->cef_window_delegate.on_window_activation_changed = on_window_activation_changed;
    window_delegate_ptr->cef_window_delegate.on_window_bounds_changed = on_window_bounds_changed;
    window_delegate_ptr->cef_window_delegate.on_window_fullscreen_transition = on_window_fullscreen_transition;
    window_delegate_ptr->cef_window_delegate.get_initial_bounds = get_initial_bounds;
    window_delegate_ptr->cef_window_delegate.get_parent_window = get_parent_window;
    window_delegate_ptr->cef_window_delegate.is_window_modal_dialog = is_window_modal_dialog;
    window_delegate_ptr->cef_window_delegate.get_initial_show_state = get_initial_show_state;
    window_delegate_ptr->cef_window_delegate.is_frameless = is_frameless;
    window_delegate_ptr->cef_window_delegate.with_standard_window_buttons = with_standard_window_buttons;
    window_delegate_ptr->cef_window_delegate.get_titlebar_height = get_titlebar_height;
    window_delegate_ptr->cef_window_delegate.accepts_first_mouse = accepts_first_mouse;
    window_delegate_ptr->cef_window_delegate.can_resize = can_resize;
    window_delegate_ptr->cef_window_delegate.can_maximize = can_maximize;
    window_delegate_ptr->cef_window_delegate.can_minimize = can_minimize;
    window_delegate_ptr->cef_window_delegate.can_close = can_close;
    window_delegate_ptr->cef_window_delegate.on_accelerator = on_accelerator;
    window_delegate_ptr->cef_window_delegate.on_key_event = on_key_event;
    window_delegate_ptr->cef_window_delegate.on_theme_colors_changed = on_theme_colors_changed;
    window_delegate_ptr->cef_window_delegate.get_window_runtime_style = get_window_runtime_style;
    window_delegate_ptr->cef_window_delegate.get_linux_window_properties = get_linux_window_properties;
    return window_delegate_ptr;
}
